package com.songcha.library_common.ui.view

import android.content.Context
import android.graphics.Canvas
import android.graphics.SurfaceTexture
import android.media.AudioManager
import android.media.MediaPlayer
import android.net.Uri
import android.util.AttributeSet
import android.view.Gravity
import android.view.Surface
import android.view.TextureView
import android.view.ViewGroup
import android.widget.FrameLayout


class SimpleVideoPlayerView
@JvmOverloads
constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyle: Int = 0,
    defRes: Int = 0
) : FrameLayout(context,attrs,defStyle,defRes),
    TextureView.SurfaceTextureListener,
    MediaPlayer.OnPreparedListener,MediaPlayer.OnErrorListener,
    MediaPlayer.OnInfoListener,
    MediaPlayer.OnCompletionListener,
    MediaPlayer.OnVideoSizeChangedListener{
    private lateinit var mMediaPlayer:MediaPlayer
    private lateinit var mTextureView:TextureView
    private var mSurfaceTexture:SurfaceTexture ?= null
    private var mSurface:Surface ?= null
    private var mSurfaceTextureAvailable = false
    //private var mIsPrepared = false
    //private var mIsPause = false
    private var mStatus:Int = STATUS_IDLE
    private var mOnPreparedListener:IOnPreparedListener? = null

    companion object{
        const val STATUS_IDLE = 1
        const val STATUS_PREPARING = 2
        const val STATUS_PREPARED = 3
        const val STATUS_PAUSE = 4
        const val STATUS_PLAYING = 5
        const val STATUS_COMPLETED = 6
        const val STATUS_STOP = 7
    }

    interface IOnPreparedListener{
        fun onPrepared()
        fun onError(e:Exception)
    }

    init {
        initView(context, attrs)
    }

    private fun initMediaPlayer(){
        mMediaPlayer = MediaPlayer()
        mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC)
        mMediaPlayer.setOnPreparedListener(this)
        mMediaPlayer.setOnVideoSizeChangedListener(this)
        mMediaPlayer.setOnCompletionListener (this)
        mMediaPlayer.setOnErrorListener(this)
        mMediaPlayer.setOnInfoListener(this)
    }

    private fun initView(context: Context, attrs: AttributeSet?){
        initMediaPlayer()


        mTextureView = TextureView(context)
        mTextureView.surfaceTextureListener = this

        val textureParams= FrameLayout.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.MATCH_PARENT
        )
        textureParams.gravity = Gravity.CENTER
        mTextureView.layoutParams = textureParams
        addView(mTextureView)
    }



    fun getMediaPlayer():MediaPlayer{
        return mMediaPlayer
    }

    fun setOnPreparedListener(listener:IOnPreparedListener){
        mOnPreparedListener = listener
    }

    private fun checkStatusIsNeedInit():Boolean{
        when(mStatus){
            STATUS_IDLE -> {
                return true
            }
            STATUS_PREPARED -> {
                startPlay()
                return false
            }
            STATUS_PLAYING -> {
                return false
            }
            STATUS_PAUSE -> {
                startPlay()
                return false
            }
            STATUS_COMPLETED -> {
                startPlay()
                return false
            }
            STATUS_STOP -> {
                return true
            }
            else -> {
                return true
            }
        }

    }

    fun startPlayUrl(url:String){
        startPlayInit {
            mMediaPlayer.setDataSource(context, Uri.parse(url))
        }
    }

    fun startPlayAssets(assetsName:String){
        startPlayInit {
            val afd = resources.assets.openFd(assetsName)
            mMediaPlayer.setDataSource(afd.fileDescriptor, afd.startOffset, afd.length)
        }
    }

    private fun startPlayInit(onSetDataSource:()->Unit){
        if(!mSurfaceTextureAvailable) return
        if(!checkStatusIsNeedInit()) return

        try{
            if(mStatus == STATUS_STOP){
                initMediaPlayer()
            }
            onSetDataSource()
            if(mSurfaceTexture != null){
                if(mSurface == null)
                    mSurface = Surface(mSurfaceTexture)
                mMediaPlayer.setSurface(mSurface)
                mMediaPlayer.prepareAsync()
                mStatus = STATUS_PREPARING
            }
        }catch (e:Exception){
            e.printStackTrace()
            mOnPreparedListener?.onError(e)
        }
    }

    fun getStatus():Int{
        return mStatus
    }

    /*fun isPrepared():Boolean{
        return mIsPrepared
    }

    fun isPause():Boolean{
        return mIsPause
    }*/


    fun startPlay(){
        //if(!mIsPrepared) return
        if(!mSurfaceTextureAvailable) return
        if(mStatus == STATUS_IDLE || mStatus == STATUS_PREPARING || mStatus == STATUS_STOP || mStatus == STATUS_PLAYING) return
        mMediaPlayer.start()
        mStatus = STATUS_PLAYING
    }

    fun pausePlay(){
        if(!mSurfaceTextureAvailable) return
        if(mStatus != STATUS_PLAYING) return
        mMediaPlayer.pause()
        mStatus = STATUS_PAUSE
    }

    fun stopPlay(){
        if(!mSurfaceTextureAvailable) return
        if(mStatus == STATUS_IDLE || mStatus == STATUS_PREPARING || mStatus == STATUS_PREPARED || mStatus == STATUS_STOP) return
        mMediaPlayer.stop()
        mMediaPlayer.release()
        mStatus = STATUS_STOP
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
    }

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        super.onLayout(changed, l, t, r, b)
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
    }

    override fun onSurfaceTextureAvailable(surface: SurfaceTexture, width: Int, height: Int) {
        if(mSurfaceTexture == null){
            mSurfaceTexture = surface
            mSurfaceTextureAvailable = true
        }else{
            mTextureView.setSurfaceTexture(mSurfaceTexture!!)
        }
    }

    override fun onSurfaceTextureSizeChanged(surface: SurfaceTexture, width: Int, height: Int) {

    }

    override fun onSurfaceTextureDestroyed(surface: SurfaceTexture): Boolean {
        return true
    }

    override fun onSurfaceTextureUpdated(surface: SurfaceTexture) {

    }

    override fun onPrepared(mp: MediaPlayer?) {
        //mIsPrepared = true
        mStatus = STATUS_PREPARED
        mOnPreparedListener?.onPrepared()
        startPlay()
    }

    override fun onError(mp: MediaPlayer?, what: Int, extra: Int): Boolean {
        return true
    }

    override fun onInfo(mp: MediaPlayer?, what: Int, extra: Int): Boolean {
        return true
    }

    override fun onCompletion(mp: MediaPlayer?) {
        mStatus = STATUS_COMPLETED
    }

    override fun onVideoSizeChanged(mp: MediaPlayer?, width: Int, height: Int) {

    }

}